// deepclone/clone
// create/new/instanceof
// get/memorized
// hasCycle/deepEquale

Object.myCreate = function (obj) {
    function fn() { };
    fn.prototype = obj;
    return new fn()
}
console.log(Object.myCreate({ a: 1 }));




function myNew(fn, ...args) {
    let newFn = Object.prototype(fn.prototype);
    let result = fn.call(newFn, ...args)
    return result instanceof object ? result : newFn
}



function myInstanceOf(obj, Obj) {
    let objProto = obj.__proto__;
    let ObjProto = Obj.prototype;

    while (true) {
        if (objProto === null) return false;
        if (objProto === ObjProto) return true;
        objProto = objProto.__proto__
    }
}
// 示例
function A() { }
let a = new A();

console.log(myInstanceOf(a, A), '---'); // true
console.log(myInstanceOf(a, Object)); // true
console.log(myInstanceOf(a, Array)); // false



function deepClone(obj, map = new WeakMap()) {
    if(obj instanceof Date){
        return new Date(obj)
    }
    if(obj instanceof RegExp){
        return new RegExp(obj)
    }
    // 普通类型
    if(obj === null || typeof obj !== 'object'){
        return obj
    }

    let Constructor = obj.constructor;
    const res = new Constructor();
    if(map.has(obj)){
        return map.get(obj)
    }
    map.set(obj, res)

    Object.keys(obj).forEach((key) => {
        if(obj.hasOwnProperty(key)){
            res[key] = deepClone(obj[key], map)
        }
    })
    return res;
}
// 示例使用
const original = {
    number: 1,
    bool: false,
    string: 'string',
    date: new Date(),
    regex: /regex/,
    array: [1, 2, 3],
    object: {
        nested: 'nested'
    },
    func: function () { console.log('hello'); }
};
const copied = deepClone(original);
console.log(copied);




function clone(obj) {
    if(obj instanceof Date){
        return new Date(obj)
    }
    if(obj instanceof RegExp){
        return new RegExp(obj)
    }
    // 普通类型
    if(obj === null || typeof obj !== 'object'){
        return obj
    }

    let Constructor = obj.constructor;
    const res = new Constructor();


    Object.keys(obj).forEach((key) => {
        if(obj.hasOwnProperty(key)){
            res[key] = obj[key]
        }
    })
    return res;
}
console.log(clone(original));



function get(obj, path, defaultValue) {
    if(typeof path === 'string'){
        const reg = /[^\[\].]+/g;
        path = path.match(reg)
    }
    for(let i = 0; i< path.length; i++){
        if(!obj) return defaultValue;
        obj = obj[path[i]]
    }
    return obj === undefined ? defaultValue : obj
}
const obj = {a:[{b: {c: 3}}]}
console.log(get(obj, ['k','0','b', 'c'], 9))
console.log(get(obj, "a[0].b.c", 9))





function memoize(func, resolver) {
    const memoized = (...args) => {
        const key = resolver ? resolver.apply(this, args) : args[0];
        if(memoized.cache.has(key)){
            return memoized.cache.get(key)
        }
        const res = func.apply(this, args);
        memoized.cache.set(key, res)
        return res;
    }
    memoized.cache = new WeakMap();
    return memoized;
}
// 示例
var object = {a: 1, b: 2}
var other = {c: 3, d: 4}

var values = memoize((object) => Object.values(object))
// 每次返回新对象，都要重新算没有缓存
var values2 = memoize((object) => Object.values(object), () => ({}))
console.log(values(object))
object.a = 2;
console.log(values(object))


function hasCycle(obj, map = new Map()){
    // 基础类型与null
    if(obj === null && typeof obj !== 'object'){
        return false;
    }
    if(map.has(obj)){
        return true;
    }
    map.set(obj, true)

    for(const key in obj){
        if(obj.hasOwnProperty(obj[key])){
            const value = obj[key];
            if(typeof value === 'object' && hasCycle(value, map)){
                return true
            }
        }
    }

    return false
}

// 示例  
const aa = {};  
const b = { aa };  
a.b = b; // 创建循环依赖  
  
console.log(hasCycle(a)); // 输出: true  


function isObject(obj) {
    return obj !== null && typeof obj === 'object';
}

function deepEqual(obj1, obj2) {
    // 处理不同类型的比较
    if (obj1 === obj2) return true;
    // 处理一个为 null 或 undefined，另一个不是的情况
    if (!isObject(obj1) || !isObject(obj2)) return false;
    // 获取对象的键
    const keys1 = Object.keys(obj1);
    const keys2 = Object.keys(obj2);
    // 如果键的数量不同，则对象不相等
    if (keys1.length !== keys2.length) return false;
    // 检查每个键对应的值是否相等
    for (let key of keys1) {
        if (!keys2.includes(key)) {
            return false;
        }
        //  hanshu
        if (typeof [obj1][key] === 'function' && typeof [obj2][key] === 'function') {
            x = [obj1][key].toString();
            y = [obj2][key].tostring();
            return x === y
        } else {
            if (!deepEqual(obj1[key], obj2[key])) {
                return false;
            }
        }
    }
    return true;
}



// 测试用例
const objA = { a: 1, b: { c: 2 } };
const objB = { a: 1, b: { c: 2 } };
const objC = { a: 1, b: { c: 3 } };

console.log(deepEqual(objA, objB)); // true
console.log(deepEqual(objA, objC)); // false